package org.gp953.order.service.impl;

import org.gp953.basic.exception.BusinessException;
import org.gp953.basic.service.impl.BaseServiceImpl;
import org.gp953.basic.util.CodeGenerateUtils;
import org.gp953.basic.util.DistanceUtil;
import org.gp953.basic.util.PageList;
import org.gp953.order.consts.OrderConsts;
import org.gp953.order.domain.ProductOrderDetail;
import org.gp953.order.domain.ProductOrder;
import org.gp953.order.domain.ProductOrderDetail;
import org.gp953.order.mapper.ProductOrderDetailMapper;
import org.gp953.order.mapper.ProductOrderDetailMapper;
import org.gp953.order.mapper.ProductOrderMapper;
import org.gp953.order.query.ProductOrderQuery;
import org.gp953.order.service.IProductOrderService;
import org.gp953.org.domain.Employee;
import org.gp953.org.domain.Shop;
import org.gp953.org.mapper.EmployeeMapper;
import org.gp953.org.mapper.ShopMapper;
import org.gp953.pay.constants.Payconsts;
import org.gp953.pay.domain.PayBill;
import org.gp953.pay.mapper.PayBillMapper;
import org.gp953.pay.service.IPayBillService;
import org.gp953.product.domain.Product;
import org.gp953.product.mapper.ProductDetailMapper;
import org.gp953.product.mapper.ProductMapper;
import org.gp953.quartz.consts.QuartzConsts;
import org.gp953.quartz.service.IQuartzService;
import org.gp953.quartz.utils.QuartzJobInfo;
import org.gp953.user.domain.LoginInfo;
import org.gp953.user.domain.User;
import org.gp953.user.domain.UserAddress;
import org.gp953.user.mapper.UserAddressMapper;
import org.gp953.user.mapper.UserMapper;
import org.gp953.user.service.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sound.midi.Soundbank;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class ProductOrderServiceImpl extends BaseServiceImpl<ProductOrder> implements IProductOrderService {

    @Autowired
    private ProductOrderMapper productOrderMapper;

    @Autowired
    private ProductOrderDetailMapper productOrderDetailMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private EmployeeMapper employeeMapper;

    @Autowired
    private IQuartzService quartzService;

    @Override
    public String submit(Map<String, Object> map, LoginInfo loginInfo) {
        // 校验数据
        Integer serviceMethod = Integer.valueOf(map.get("service_method").toString());
        Long addressId = Long.valueOf(map.get("address_id").toString());
        Integer payMethod = Integer.valueOf(map.get("pay_method").toString());
        Long productId = Long.valueOf(map.get("product_id").toString());
        Long buyNum = Long.valueOf(map.get("buyNum").toString());
        if (serviceMethod == null
                || addressId == null
                || payMethod == null
                || productId == null) {
            throw new BusinessException("订单数据异常");
        }

        User user = userMapper.queryByLoginInfoId(loginInfo.getId());
        Product product = productMapper.loadById(productId);
        // 设置该服务的销量，生成订单就算销售出去了
        product.setSalecount(product.getSalecount()+buyNum);
        productMapper.update(product);
        // 生成订单
        ProductOrder productOrder = initProductOrder(product, user, serviceMethod, buyNum);
        // 返回自增id存放到服务订单详情表中
        productOrderMapper.save(productOrder);

        // 生成服务订单详情表
        ProductOrderDetail productOrderDetail = initProductOrderDetail(productOrder,product,buyNum);
        productOrderDetailMapper.save(productOrderDetail);

        // 生成支付账单
        PayBill payBill = initPayBill(payMethod, user, productOrder);

        /*QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(QuartzConsts.PAY_OVER_TIME_ADOPT_ORDER + productOrder.getId());
        Map<String, Object> quartzMap = new HashMap<>();
        quartzMap.put("type", QuartzConsts.PAY_OVER_TIME_ADOPT_ORDER);
        quartzMap.put("orderId", productOrder.getId());
        jobInfo.setParams(quartzMap);
        jobInfo.setFireDate(productOrder.getLastPayTime());
        quartzService.addJob(jobInfo);
        */
        QuartzJobInfo jobInfo = new QuartzJobInfo();
        jobInfo.setJobName(QuartzConsts.PAY_OVER_TIME_PRODUCT_ORDER + productOrder.getId());
        Map<String, Object> quartzMap = new HashMap<>();
        quartzMap.put("type", QuartzConsts.PAY_OVER_TIME_PRODUCT_ORDER);
        quartzMap.put("orderId", productOrder.getId());
        jobInfo.setParams(quartzMap);
        jobInfo.setFireDate(productOrder.getLastPayTime());
        quartzService.addJob(jobInfo);

        // 支付是另一个模块，应该调用统一的支付接口而不是直接调用mapper层
        String payData = payBillService.payRequest(payBill);
        System.out.println(payData);
        return payData;
    }

    @Override
    public ProductOrder queryByUnionPaySn(String unionPaySn) {
        return productOrderMapper.queryByUnionPaySn(unionPaySn);
    }

    @Override
    public void cancelOrder(Long orderId) {
        ProductOrder productOrder = productOrderMapper.loadById(orderId);
        // 将订单状态设置为取消并存回数据库
        productOrder.setState(OrderConsts.ORDER_STATE_CANCEL);
        productOrderMapper.update(productOrder);

    }


    private PayBill initPayBill(Integer payMethod, User user, ProductOrder productOrder) {
        // 支付 先生成支付单
        PayBill payBill = new PayBill();
        payBill.setDigest(productOrder.getDigest());
        payBill.setMoney(productOrder.getPrice());
        payBill.setUnionPaySn(productOrder.getPaySn());
        // 设置支付账单状态
        payBill.setState(Payconsts.PAY_STATE_TOBEPAID);
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + Payconsts.PAY_TIME_OUT));
        payBill.setPayChannel(payMethod);
        payBill.setBusinessType(Payconsts.BUSINESS_TYPE_PRODUCT);
        // 设置支付账单的关联订单id
        payBill.setBusinessKey(productOrder.getId());
        payBill.setUser_id(productOrder.getUser().getId());
        payBill.setShop_id(productOrder.getShop().getId());
        payBill.setNickName(user.getUsername());
        return payBill;
    }

    @Override
    public PageList<ProductOrder> admin(ProductOrderQuery query, LoginInfo loginInfo) {
        Employee employee = employeeMapper.loadByLoginInfoId(loginInfo.getId());
        if (employee.getShop_id() != null) {
            query.setShopId(employee.getShop_id());
        }
        return super.queryPageData(query);
    }

    @Override
    public PageList<ProductOrder> user(ProductOrderQuery query, LoginInfo loginInfo) {
        User user = userMapper.queryByLoginInfoId(loginInfo.getId());
        query.setUserId(user.getId());
        return super.queryPageData(query);
    }

    @Override
    public void deleteQuartzJobByOrderId(Long productOrderId) {
        ProductOrder productOrder = productOrderMapper.loadById(productOrderId);
        if (productOrder.getState()==0) {
            // 将超时未支付的订单取消
            productOrder.setState(OrderConsts.ORDER_STATE_CANCEL);
            productOrderMapper.update(productOrder);

            System.out.println("超时未支付，将"+productOrder.getDigest()+"取消了");
            /*//支付单也要修改
            String paySn = productOrder.getPaySn();
            PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
            payBill.setState(-1);
            payBillMapper.update(payBill);*/
        }
    }

    /*@Override
    public ProductOrder queryByUnionPaySn(String unionPaySn) {
        return productOrderMapper.queryByUnionPaySn(unionPaySn);
    }

    @Override
    public void deleteQuartzJobByOrderId(Long orderId) {
        ProductOrder productOrder = productOrderMapper.loadById(orderId);
        if (productOrder.getState() == 0) {
            productOrder.setState(-1);
            // 这里可以考虑直接上架服务  @TODO
            productOrderMapper.update(productOrder);
            System.out.println("quartz 触发后取消编号为：" + orderId + "的订单");
        }
    }*/

    private ProductOrderDetail initProductOrderDetail(ProductOrder productOrder,Product product,Long buyNum) {
        ProductOrderDetail productOrderDetail = new ProductOrderDetail();
        // 通过用户详细地址复制到地址订单中
        BeanUtils.copyProperties(productOrder,productOrderDetail);
        BeanUtils.copyProperties(product,productOrderDetail);
        // 关联订单表id
        productOrderDetail.setOrder_id(productOrder.getId());
        productOrderDetail.setSalecount(buyNum);
        productOrderDetail.setCreatetime(new Date());
        return productOrderDetail;
    }

    private ProductOrder initProductOrder(Product product, User user, Integer serviceMethod,Long buyNum) {

        ProductOrder order = new ProductOrder();
        // 设置订单摘要信息
        order.setDigest("[摘要]" + product.getName() + "服务订单！");
        // 设置订单的状态
        order.setState(OrderConsts.ORDER_STATE_TO_BE_PAID);//待支付
        // 设置订单成本价格
        order.setPrice(product.getCostprice());
        // 通过工具类CodeGenerateUtils的generateOrderSn()方法生成订单的唯一编号
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId());
        // 设置订单的唯一编号
        order.setOrderSn(orderSn);
        // 设置订单中的服务id
        order.setProduct_id(product.getId());
        // 设置订单总价
        order.setPrice(product.getSaleprice().multiply(new BigDecimal(buyNum)));
        // 设置订单中够买人的id信息
        order.setUser(user);
        // 设置最后支付时间
        order.setLastPayTime(new Date(System.currentTimeMillis() + Payconsts.PAY_TIME_OUT));
        // 设置订单中收购店铺的id
        order.setShop(product.getShop());
        // 生成统一支付单号，订单和支付单都需要所以现在订单中生成
        String unionPaySn = CodeGenerateUtils.generateUnionPaySn();
        order.setPaySn(unionPaySn);
        return order;
    }


}
